package com.ryan.framework.dao.impl;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.hibernate.Criteria;
import org.hibernate.Hibernate;
import org.hibernate.LockMode;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.CriteriaSpecification;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projection;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.hibernate.engine.spi.NamedQueryDefinition;
import org.hibernate.engine.spi.NamedSQLQueryDefinition;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.internal.CriteriaImpl;
import org.hibernate.metadata.ClassMetadata;
import org.hibernate.transform.ResultTransformer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Repository;

import com.ryan.dictionary.framework.enums.PageInitDataEnum;
import com.ryan.framework.dao.BaseHibernateDao;
import com.ryan.framework.model.Model;
import com.ryan.framework.tag.pagination.Page;

@Repository
public class BaseHibernateDaoSupport<M extends Model, PK extends Serializable> implements BaseHibernateDao<M,PK>{ 
	protected Logger logger = LoggerFactory.getLogger(getClass());

	/**
	 * 持久化类
	 */
	protected Class<M> entityClass;

    /** 
     * Hibernate Session 工厂 
     */       
    @Autowired  
    @Qualifier("sessionFactory")
    private SessionFactory sessionFactory;  

	/**
	 * 通过子类的泛型定义对象类型Class.
	 * eg.
	 * public class UserDao extends DaoSupport<User, Long>
	 */
	@SuppressWarnings("unchecked")
	public BaseHibernateDaoSupport() {
        Type genType = getClass().getGenericSuperclass();  
        if (genType instanceof ParameterizedType) {  
            Type[] params = ((ParameterizedType) genType).getActualTypeArguments();  
            this.entityClass = (Class<M>) params[0];  
        }  
    }

	/**
	 * 通过构造函数定义对象类型Class.
	 */
	public BaseHibernateDaoSupport(Class<M> entityClass) {
		this.entityClass = entityClass;    
	}
	  
	public Type getModelType() {
		return entityClass;
	}

    public Session getSession() {
        return sessionFactory.getCurrentSession();
    }


	public M save(final M entity) {
		getSession().saveOrUpdate(entity);
		logger.debug("save entity: {}", entity);
		return entity;
	}

	public void delete(final M entity) {
		getSession().delete(entity);
		logger.debug("delete entity: {}", entity);
	}

	public void delete(final PK id) {
		delete(get(id));
		logger.debug("delete entity {},id is {}", entityClass.getSimpleName(), id);
	}

	@SuppressWarnings("unchecked")
	public M get(final PK id) {
		return (M) getSession().get(entityClass, id);
	}

	@SuppressWarnings({ "deprecation", "unchecked" })
	public M getForUpdate(final PK id) {
		return (M) getSession().get(entityClass, id, LockMode.UPGRADE);
	}

	public List<M> get(final Collection<PK> ids) {
		return find(Restrictions.in(getIdName(), ids));
	}

	public List<M> getAll() {
		return find();
	}

	@SuppressWarnings("unchecked")
	public List<M> getAll(Page page) {
		return createCriteria(page).list();
	}

	@SuppressWarnings("unchecked")
	public List<M> getAll(String orderByProperty, boolean isAsc) {
		Criteria c = createCriteria();
		if (isAsc) {
			c.addOrder(Order.asc(orderByProperty));
		} else {
			c.addOrder(Order.desc(orderByProperty));
		}
		return c.list();
	}

	public List<M> findBy(final String propertyName, final Object value) {
		Criterion criterion = Restrictions.eq(propertyName, value);
		return find(criterion);
	}

	@SuppressWarnings("unchecked")
	public M findUniqueBy(final String propertyName, final Object value) {
		Criterion criterion = Restrictions.eq(propertyName, value);
		return (M) createCriteria(criterion).setMaxResults(1).uniqueResult();
	}

	@SuppressWarnings("unchecked")
	public <X> List<X> find(final String hql, final Object... values) {
		return createQuery(hql, values).list();
	}

	@SuppressWarnings("unchecked")
	public <X> List<X> find(final String hql, Page page, final Object... values) {
		Query q = createQuery(hql, values);
		if (page != null) {
			Integer totalRecord = countHqlResult(hql, values);
			page.setTotalRecord(totalRecord);
			this.generatePage(page, totalRecord);
			q.setFirstResult((page.getTargetPage()-1) * page.getPageSize());
			q.setMaxResults(page.getPageSize());
		}
		return q.list();
	}

	@SuppressWarnings("unchecked")
	public <X> List<X> find(final String hql, final Map<String, ?> values) {
		return createQuery(hql, values).list();
	}

	@SuppressWarnings("unchecked")
	public <X> Iterator<X> iterator(String hql, Map<String, ?> values) {
		return createQuery(hql, values).iterate();
	}

	@SuppressWarnings("unchecked")
	public <X> List<X> find(String hql, Page page, Map<String, ?> values) {
		Query q = createQuery(hql, values);
		if (page != null) {
			Integer totalRecord = countHqlResult(hql, values);
			page.setTotalRecord(totalRecord);
			this.generatePage(page, totalRecord);
			q.setFirstResult((page.getTargetPage()-1) * page.getPageSize());
			q.setMaxResults(page.getPageSize());
		}
		return q.list();
	}

	@SuppressWarnings("unchecked")
	public List<M> find(final Criterion... criterions) {
		Criteria criteria = createCriteria(criterions);
		return criteria.list();
	}
	
	@SuppressWarnings("unchecked")
	public List<M> find(final List<Criterion> criterionList) {
		return createCriteria(criterionList).list();
	}

	@SuppressWarnings("unchecked")
	public List<M> find(Order[] orders, Criterion... criterions) {
		Criteria criteria = createCriteria(criterions);
		if (orders != null) {
			for (int i = 0; i < orders.length; i++) {
				criteria.addOrder(orders[i]);
			}
		}
		return criteria.list();
	}

	@SuppressWarnings("unchecked")
	public List<M> find(Page page, Criterion... criterions) {
		Criteria criteria = createCriteria(page, criterions);
		return criteria.list();
	}
	
	@SuppressWarnings("unchecked")
	public List<M> find(Page page, List<Criterion> criterions) {
		Criteria criteria = createCriteria(page, criterions);
		return criteria.list();
	}

	@SuppressWarnings("unchecked")
	public List<M> find(Page page, Order[] orders, Criterion... criterions) {
		Criteria criteria = createCriteria(page, criterions);
		if (orders != null) {
			for (int i = 0; i < orders.length; i++) {
				criteria.addOrder(orders[i]);
			}
		}
		return criteria.list();
	}

	@SuppressWarnings("unchecked")
	public <X> X findUnique(final String hql, final Object... values) {
		return (X) createQuery(hql, values).setMaxResults(1).uniqueResult();
	}

	@SuppressWarnings("unchecked")
	public <X> X findUnique(final String hql, final Map<String, ?> values) {
		return (X) createQuery(hql, values).setMaxResults(1).uniqueResult();
	}

	@SuppressWarnings("unchecked")
	public <X> X sum(String propertyName, Criterion... criterions) {
		Criteria criteria = createCriteria(criterions);
		criteria.setProjection(Projections.sum(propertyName));
		return (X) criteria.uniqueResult();
	}

	@SuppressWarnings("unchecked")
	public <X> X avg(String propertyName, Criterion... criterions) {
		Criteria criteria = createCriteria(criterions);
		criteria.setProjection(Projections.avg(propertyName));
		return (X) criteria.uniqueResult();
	}

	@SuppressWarnings("unchecked")
	public <X> X max(String propertyName, Criterion... criterions) {
		Criteria criteria = createCriteria(criterions);
		criteria.setProjection(Projections.max(propertyName));
		return (X) criteria.uniqueResult();
	}

	@SuppressWarnings("unchecked")
	public <X> X min(String propertyName, Criterion... criterions) {
		Criteria criteria = createCriteria(criterions);
		criteria.setProjection(Projections.min(propertyName));
		return (X) criteria.uniqueResult();
	}

	public long count(Criterion... criterions) {
		Criteria criteria = createCriteria(criterions);
		criteria.setProjection(Projections.rowCount());
		return (Long) criteria.uniqueResult();
	}

	@SuppressWarnings("unchecked")
	public <X> List<X> findByNamedQuery(String queryName, Page page, Object... values) {
		Query query = getSession().getNamedQuery(queryName);
		if (page != null) {
			Integer totalRecord = countNamedQueryResult(queryName, values);
			page.setTotalRecord(totalRecord);
			this.generatePage(page, totalRecord);
			query.setFirstResult((page.getTargetPage()-1) * page.getPageSize());
			query.setMaxResults(page.getPageSize());
		}
		if (values != null) {
			for (int i = 0; i < values.length; i++) {
				query.setParameter(i, values[i]);
			}
		}
		return query.list();
	}

	/*
	 * (non-Javadoc)
	 * @see com.bill99.seashell.orm.BaseDao#findByNamedQuery(java.lang.String, com.bill99.seashell.orm.pagination.Page, java.util.Map)
	 */
	@SuppressWarnings("unchecked")
	public <X> List<X> findByNamedQuery(String queryName, Page page, Map<String, ?> values) {
		Query query = getSession().getNamedQuery(queryName);
		if (page != null) {
			Integer totalRecord = countNamedQueryResult(queryName, values);
			page.setTotalRecord(totalRecord);
			this.generatePage(page, totalRecord);
			query.setFirstResult((page.getTargetPage()-1) * page.getPageSize());
			query.setMaxResults(page.getPageSize());
		}
		if (values != null) {
			query.setProperties(values);
		}
		return query.list();
	}
	/* (non-Javadoc)
	 * @see com.bill99.seashell.orm.BaseDao#batchExecute(java.lang.String, java.lang.Object)
	 */
	public int execute(final String hql, final Object... values) {
		return createQuery(hql, values).executeUpdate();
	}

	/* (non-Javadoc)
	 * @see com.bill99.seashell.orm.BaseDao#batchExecute(java.lang.String, java.util.Map)
	 */
	public int execute(final String hql, final Map<String, ?> values) {
		return createQuery(hql, values).executeUpdate();
	}

	protected Query createQuery(final String queryString, final Object... values) {
		Query query = getSession().createQuery(queryString);
		if (values != null) {
			for (int i = 0; i < values.length; i++) {
				query.setParameter(i, values[i]);
			}
		}
		return query;
	}

	protected Query createQuery(final String queryString, final Map<String, ?> values) {
		Query query = getSession().createQuery(queryString);
		if (values != null) {
			query.setProperties(values);
		}
		return query;
	}

	@SuppressWarnings("unchecked")
	public M findUnique(final Criterion... criterions) {
		return (M) createCriteria(criterions).setMaxResults(1).uniqueResult();
	}

	protected Criteria createCriteria(final Criterion... criterions) {
		Criteria criteria = getSession().createCriteria(entityClass);
		for (Criterion criterion : criterions) {
			criteria.add(criterion);
		}
		return criteria;
	}

	protected Criteria createCriteria(List<Criterion> criterionList) {
		Criteria criteria = getSession().createCriteria(entityClass);
		for (Criterion criterion : criterionList) {
			criteria.add(criterion);
		}
		return criteria;
	}

	/**
	 * 初始化对象.
	 * 使用load()方法得到的仅是对象Proxy, 在传到View层前需要进行初始化.
	 * 如果传入entity, 则只初始化entity的直接属性,但不会初始化延迟加载的关联集合和属性.
	 * 如需初始化关联属性,需执行:
	 * Hibernate.initialize(user.getRoles())，初始化User的直接属性和关联集合.
	 * Hibernate.initialize(user.getDescription())，初始化User的直接属性和延迟加载的Description属性.
	 */
	protected void initProxyObject(Object proxy) {
		Hibernate.initialize(proxy);
	}

	/**
	 * Flush当前Session的数据到数据库.
	 */
	protected void flush() {
		getSession().flush();
	}
	
	/**
	 * 清除当前Session
	 */
	protected void clear() {
		getSession().clear();
	}

	public M refresh(M entity) {
		getSession().refresh(entity);
		return entity;
	}
	
	public void evict(M entity) {
		getSession().evict(entity);
	};
	
	public String getIdName() {
		ClassMetadata meta = sessionFactory.getClassMetadata(entityClass);
		return meta.getIdentifierPropertyName();
	}

	@SuppressWarnings("unchecked")
	public boolean isPropertyUnique(final String propertyName, final Object newValue, final Object oldValue) {
		if (newValue == null || newValue.equals(oldValue)) {
			return true;
		}
		Criterion criterion = Restrictions.eq(propertyName, newValue);
		List<M> list = createCriteria(criterion).list();
		return list.isEmpty();
	}

	public int executeNamedQuery(String queryName, Object... values) {
		Query query = getSession().getNamedQuery(queryName);
		if (values != null) {
			for (int i = 0; i < values.length; i++) {
				query.setParameter(i, values[i]);
			}
		}
		return query.executeUpdate();
	}

	public int executeSqlUpdate(final String nativeSql, final Object... values) {
		Query query = getSession().createSQLQuery(nativeSql);
		if (values != null) {
			for (int i = 0; i < values.length; i++) {
				query.setParameter(i, values[i]);
			}
		}
		return query.executeUpdate();
	}
	
	@SuppressWarnings("unchecked")
	public <X> List<X> executeSql(String nativeSql, Object... values) {
		Query query = getSession().createSQLQuery(nativeSql);
		if (values != null) {
			for (int i = 0; i < values.length; i++) {
				query.setParameter(i, values[i]);
			}
		}
		return query.list();
	}

	public BigDecimal getSeqNextValue(String sequenceName) {
		String sql = "SELECT " + sequenceName + ".NEXTVAL FROM Dual";
		Object nextValue = getSession().createSQLQuery(sql).uniqueResult();
		return (BigDecimal) nextValue;
	}

	/**
	 * 执行count查询获得本次Criteria查询所能获得的对象总数.
	 */
	@SuppressWarnings("unchecked")
	private int countCriteriaResult(final Criteria c) {
		CriteriaImpl impl = (CriteriaImpl) c;

		// 先把Projection、ResultTransformer、OrderBy取出来,清空三者后再执行Count操作
		Projection projection = impl.getProjection();
		ResultTransformer transformer = impl.getResultTransformer();

		List<CriteriaImpl.OrderEntry> orderEntries = null;
		try {
			orderEntries = (List<CriteriaImpl.OrderEntry>) getFieldValue(impl, "orderEntries");
			setFieldValue(impl, "orderEntries", new ArrayList<CriteriaImpl.OrderEntry>());
		} catch (Exception e) {
			logger.error("impossible exception:{}", e.getMessage());
		}

		// 执行Count查询
		Integer totalRecordObject = (Integer) c.setProjection(Projections.rowCount()).uniqueResult();
		Integer totalRecord = (totalRecordObject != null) ? totalRecordObject.intValue() : new Integer(0);

		// 将之前的Projection,ResultTransformer和OrderBy条件重新设回去
		c.setProjection(projection);

		if (projection == null) {
			c.setResultTransformer(CriteriaSpecification.ROOT_ENTITY);
		}
		if (transformer != null) {
			c.setResultTransformer(transformer);
		}
		try {
			setFieldValue(impl, "orderEntries", orderEntries);
		} catch (Exception e) {
			logger.error("impossible exception:{}", e.getMessage());
		}

		return totalRecord;
	}
	
	/**
	 * 执行count查询获得本次Sql查询所能获得的对象总数.
	 * 
	 * 本函数只能自动处理简单的sql语句,复杂的sql查询请另行编写count语句查询.
	 */
	private int countNamedQueryResult(final String queryName, final Object...values) {
		Query query = createCountNamedQuery(queryName);
		if (values != null) {
			for (int i = 0; i < values.length; i++) {
				query.setParameter(i, values[i]);
			}
		}
		Long count = (Long) query.uniqueResult();
		return (count != null) ? count.intValue() : 0;
	}

	/**
	 * 执行count查询获得本次Sql查询所能获得的对象总数.
	 * 
	 * 本函数只能自动处理简单的sql语句,复杂的sql查询请另行编写count语句查询.
	 */
	private int countNamedQueryResult(final String queryName, final Map<String, ?> values ) {
		Query query = createCountNamedQuery(queryName);
		if (values != null) {
			query.setProperties(values);
		}
		Long count = (Long) query.uniqueResult();
		return (count != null) ? count.intValue() : 0;
	}
	
	/**
	 * 创建执行count查询Query对象.
	 * 
	 * 本函数只能自动处理简单的sql语句,复杂的sql查询请另行编写count语句查询.
	 */
	private Query createCountNamedQuery(final String queryName) {
		NamedQueryDefinition nqd = ((SessionFactoryImplementor)sessionFactory).getNamedQuery(queryName);
		Query query = null;
		if (nqd != null) {//namedQuery来自于.hbm.xml映射文件中的<query>
			String countSql = prepareCountHql(nqd.getQueryString());
			query = getSession().createQuery(countSql);
		} else {//namedQuery来自于.hbm.xml映射文件中的<sql-query>
			NamedSQLQueryDefinition nsqd = ((SessionFactoryImplementor)sessionFactory).getNamedSQLQuery(queryName);
			String countSql = prepareCountHql(nsqd.getQueryString());
			query = getSession().createSQLQuery(countSql);
		}
		return query;
	}
	
	/**
	 * 执行count查询获得本次Hql查询所能获得的对象总数.
	 * 
	 * 本函数只能自动处理简单的hql语句,复杂的hql查询请另行编写count语句查询.
	 */
	private int countHqlResult(final String hql, final Object... values) {
		String countHql = prepareCountHql(hql);
		try {
			Long count = findUnique(countHql, values);
			return count.intValue();
		} catch (Exception e) {
			throw new RuntimeException("hql can't be auto count, hql is:" + countHql, e);
		}
	}
	
	/**
	 * 执行count查询获得本次Hql查询所能获得的对象总数.
	 * 
	 * 本函数只能自动处理简单的hql语句,复杂的hql查询请另行编写count语句查询.
	 */
	private int countHqlResult(final String hql, final Map<String, ?> values) {
		String countHql = prepareCountHql(hql);
		try {
			Long count = findUnique(countHql, values);
			return count.intValue();
		} catch (Exception e) {
			throw new RuntimeException("hql can't be auto count, hql is:" + countHql, e);
		}
	}
	
	/**
	 * select子句与order by子句会影响count查询,进行简单的排除.
	 * 
	 * @param orgHql
	 * @return
	 */
	private String prepareCountHql(String orgHql) {
		String upperCaseHql = orgHql.toUpperCase();
		int startIndex = upperCaseHql.indexOf("FROM ");
		int endIndex = upperCaseHql.indexOf("ORDER BY");
		if (endIndex > -1) {
			return "select count(*) from " + orgHql.substring(startIndex + 5, endIndex);
		} else {
			return "select count(*) from " + orgHql.substring(startIndex + 5);
		}
	}
	
	/**
	 * 直接读取对象属性值, 无视private/protected修饰符, 不经过getter函数.
	 */
	private Object getFieldValue(final Object obj, final String fieldName) {
		Field field = getAccessibleField(obj, fieldName);

		if (field == null) {
			throw new IllegalArgumentException("Could not find field [" + fieldName + "] on target [" + obj + "]");
		}

		Object result = null;
		try {
			result = field.get(obj);
		} catch (IllegalAccessException e) {
			logger.error("impossible exception:{}", e.getMessage());
		}
		return result;
	}

	/**
	 * 直接设置对象属性值, 无视private/protected修饰符, 不经过setter函数.
	 */
	private void setFieldValue(final Object obj, final String fieldName, final Object value) {
		Field field = getAccessibleField(obj, fieldName);

		if (field == null) {
			throw new IllegalArgumentException("Could not find field [" + fieldName + "] on target [" + obj + "]");
		}

		try {
			field.set(obj, value);
		} catch (IllegalAccessException e) {
			logger.error("impossible exception:{}", e.getMessage());
		}
	}

	/**
	 * 循环向上转型, 获取对象的DeclaredField,	 并强制设置为可访问.
	 * 
	 * 如向上转型到Object仍无法找到, 返回null.
	 */
	private Field getAccessibleField(final Object obj, final String fieldName) {
		for (Class<?> superClass = obj.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()) {
			try {
				Field field = superClass.getDeclaredField(fieldName);
				field.setAccessible(true);
				return field;
			} catch (NoSuchFieldException e) {//NOSONAR
				// Field不在当前类定义,继续向上转型
			}
		}
		return null;
	}
	
	private Criteria createCriteria(Page page, Criterion... criterions) {
		Criteria criteria = createCriteria(criterions);
		generatePageCriteria(page,criteria);
		return criteria;
	}
	
	private Criteria createCriteria(Page page, List<Criterion> criterionList) {
		Criteria criteria = createCriteria(criterionList);
		generatePageCriteria(page,criteria);
		return criteria;
	}
	
	private void generatePageCriteria(Page page, Criteria criteria){
		if (page != null) {
			Integer totalRecord = countCriteriaResult(criteria);
			page.setTotalRecord(totalRecord);
			this.generatePage(page,totalRecord);
			criteria.setFirstResult((page.getTargetPage()-1) * page.getPageSize());
			criteria.setMaxResults(page.getPageSize());
		}
	}
	
	private void generatePage(Page page,Integer totalRecord){
		if(totalRecord>PageInitDataEnum.TOTAL_RECORD.getValue()){
			if(page.getPageSize()>=totalRecord){
				page.setTotalRecord(totalRecord);
				page.setPageSize(totalRecord);
				page.setTargetPage(PageInitDataEnum.TARGET_PAGE.getValue());
			}else if(page.getTargetPage()>(((totalRecord.intValue() - 1) / page.getPageSize().intValue()) + 1)){
				page.setTargetPage(((totalRecord.intValue() - 1) / page.getPageSize().intValue()) + 1);
			}
			Integer totalPage = getTotalPage(page.getPageSize(),totalRecord);
			if(page.getTargetPage()>totalPage){
				page.setTargetPage(totalPage);
			}
		}else{
			page.setPageSize(PageInitDataEnum.PAGE_SIZE.getValue());
			page.setTargetPage(PageInitDataEnum.TARGET_PAGE.getValue());
		}
	}
	
	public Integer getTotalPage(Integer pageSize,Integer totalRecord) {
		if (totalRecord.intValue() <= PageInitDataEnum.TOTAL_RECORD.getValue()) {
			return PageInitDataEnum.TOTAL_RECORD.getValue();
		} else {
			return ((totalRecord.intValue() - 1) / pageSize.intValue()) + 1;
		}
	}
    
    
    
	/*
    *//** 
     *  
     * <br/>Description:根据传入的实体向数据库添加一条记录 
     *  
     * @author Eric 
     * @param obj 
     * @throws AppException 
     *//*  
    public void addObject(Object obj) throws AppException{  
        log.debug("BaseDao addObject object " + obj);  
        try{  
            sessionFactory.getCurrentSession().save(obj);  
        }catch(Exception e){  
            throw new AppException("根据传入对象添加记录异常，请联系管理员！",e);  
        }  
    }  
  
    *//** 
     *  
     * <br/>Description:强制刷新Hibernate缓存提交数据更改操作 
     *  
     * @author Eric 
     * @return 
     * @version V1.0 
     *//*  
    public void dbFlush() throws AppException{  
        log.debug("BaseDao addObject dbFlush");  
        try{  
            sessionFactory.getCurrentSession().flush();  
        }catch(Exception e){  
            throw new AppException("刷新缓存失败，请联系管理员！",e);  
        }  
    }  
  
    *//** 
     *  
     * <br/>Description:根据传入的实体向数据库添加一条记录,返回插入记录的主键 
     *  
     * @author Eric 
     * @param obj 
     * @return 
     * @throws AppException 
     *//*  
    public String addObjectPK(Object obj) throws AppException{  
        log.debug("BaseDao addObjectPK object " + obj);  
        String id = null;  
        try{  
            id = (String) sessionFactory.getCurrentSession().save(obj);  
        }catch(Exception e){  
            throw new AppException("根据传入对象添加记录异常，请联系管理员！",e);  
        }  
        return id;  
    }  
  
    *//** 
     *  
     * <br/>Description:根据传入的实体从数据库删除一条记录 
     *  
     * @author Eric 
     * @param obj 
     * @throws AppException 
     *//*  
    public void deleteObject(Object obj) throws AppException{  
        log.debug("BaseDao deleteObject object " + obj);  
        try{  
            sessionFactory.getCurrentSession().delete(obj);  
        }catch(Exception e){  
            throw new AppException("根据传入对象删除记录异常，请联系管理员！",e);  
        }  
    }  
  
    *//** 
     *  
     * <br/>Description:根据传入的实体与ID从数据库删除一条记录 
     *  
     * @author Eric 
     * @param cls 
     * @param id 
     * @throws AppException 
     *//*  
    @SuppressWarnings({"rawtypes"})  
    public void deleteObject(Class cls,Serializable id) throws AppException{  
        log.debug("BaseDao deleteObject Class " + cls.getName() + " id " + id.toString());  
        try{  
            this.deleteObject(sessionFactory.getCurrentSession().get(cls,id));  
        }catch(Exception e){  
            throw new AppException("根据传入对象与ID删除记录异常，请联系管理员！",e);  
        }  
    }  
  
    *//** 
     *  
     * <br/>Description:根据传入的实体修改数据库中一条记录 
     *  
     * @author Eric 
     * @param obj 
     * @throws AppException 
     *//*  
    public void updateObject(Object obj) throws AppException{  
        log.debug("BaseDao updateObject object " + obj);  
        try{  
            sessionFactory.getCurrentSession().update(obj);  
        }catch(Exception e){  
            throw new AppException("根据传入对象更新记录异常，请联系管理员！");  
        }  
    }  
  
    *//** 
     *  
     * <br/>Description:根据传入的实体修改数据库中一条记录,返回更新记录的主键 
     *  
     * @author Eric 
     * @param obj 
     * @return 
     * @throws AppException 
     *//*  
    public String updateObjectPK(Object obj) throws AppException{  
        log.debug("BaseDao updateObjectPK object " + obj);  
        String id = null;  
        try{  
            id = this.addObjectPK(obj);  
        }catch(Exception e){  
            throw new AppException("根据传入对象更新记录异常，请联系管理员！",e);  
        }  
        return id;  
    }  
  
    *//** 
     *  
     * <br/>Description:根据传入的实体添加或修改数据库中一条记录 
     *  
     * @author Eric 
     * @param obj 
     * @throws AppException 
     *//*  
    public void addOrUpdate(Object obj) throws AppException{  
        log.debug("BaseDao updateObjectPK object " + obj);  
        try{  
            sessionFactory.getCurrentSession().saveOrUpdate(obj);  
        }catch(Exception e){  
            throw new AppException("根据传入对象保存数据异常，请联系管理员！",e);  
        }  
    }  
  
    *//** 
     *  
     * <br/>Description:根据ID返回一个对象 
     *  
     * @author Eric 
     * @param cls 
     * @param id 
     * @return 
     * @throws AppException 
     *//*  
    @SuppressWarnings({"rawtypes"})  
    public Object findObjectById(Class cls,Serializable id) throws AppException{  
        log.debug("BaseDao findObjectById Class " + cls.getName() + " id " + id.toString());  
        Object obj = null;  
        try{  
            obj = sessionFactory.getCurrentSession().get(cls,id);  
        }catch(Exception e){  
            throw new AppException("根据对象及ID查询记录异常，请联系管理员！",e);  
        }  
        return obj;  
    }  
  
    *//** 
     *  
     * <br/>Description:根据实体返回一个集合 
     *  
     * @author Eric 
     * @param cls 
     * @return 
     * @throws AppException 
     *//*  
    @SuppressWarnings({"rawtypes"})  
    public List findAllData(Class cls) throws AppException{  
        log.debug("BaseDao findAllData Class " + cls.getName());  
        List list = null;  
        try{  
            list = sessionFactory.getCurrentSession().createQuery(" from " + cls.getName() + "").list();  
        }catch(Exception e){  
            throw new AppException("根据对象查询记录异常，请联系管理员！",e);  
        }  
        return list;  
    }  
  
    *//** 
     *  
     * <br/>Description:根据传入HQL语句返回一个集合(供DAO使用) 
     *  
     * @author Eric 
     * @param hql 
     * @return 
     * @throws AppException 
     *//*  
    @SuppressWarnings("rawtypes")  
    public List findHQLObject(String hql) throws AppException{  
        try{  
            return sessionFactory.getCurrentSession().createQuery(hql).list();  
        }catch(Exception e){  
            throw new AppException("根据传入条件语句查询记录异常，请联系管理员！");  
        }  
    }  
  
    *//** 
     *  
     * <br/>Description:按HQL提供者别名与条件查询集合 
     *  
     * @author Eric 
     * @param hqlProviderSet 
     * @param queryName 
     * @param paramMap 
     * @return 
     * @throws AppException 
     *//*  
    
    @SuppressWarnings("rawtypes") 
    public List findListByHqlName(IHqlProviderSet hqlProviderSet,String queryName,Map paramMap) throws AppException{  
        String hql;  
        try{  
            hql = hqlProviderSet.getHqlByQryName(queryName);  
            Query query = sessionFactory.getCurrentSession().createQuery(hql);  
            if(paramMap != null){  
                hqlArgs(paramMap,query);  
            }  
  
            return query.list();  
        }catch(Exception e){  
            throw new AppException("按HQL提供者别名与条件查询集合异常，请联系管理员！",e);  
        }  
    }  
  
    *//** 
     *  
     * <br/>Description:按HQL提供者别名、条件、分页信息查询集合 
     *  
     * @author Eric 
     * @param hqlProviderSet 
     * @param queryName 
     * @param paramMap 
     * @param page 
     * @return 
     * @throws AppException 
     *//*   
    
    @SuppressWarnings("rawtypes") 
    public List findListByHqlName(IHqlProviderSet hqlProviderSet,String queryName,Map paramMap,PageEntity page) throws AppException{  
        String hql;  
        try{  
            hql = hqlProviderSet.getHqlByQryName(queryName);  
  
            Query query = sessionFactory.getCurrentSession().createQuery(hql);  
  
            if(paramMap != null){  
                hqlArgs(paramMap,query);  
            }  
  
            query.setFirstResult((page.getPageNo() - 1) * page.getPageSize());  
            query.setMaxResults(page.getPageSize());  
  
            return query.list();  
        }catch(Exception e){  
            throw new AppException("按HQL提供者别名、条件、分页信息查询集合异常，请联系管理员！",e);  
        }  
    }  
  
    *//** 
     *  
     * <br/>Description:根据传入实体对象返回总记录数 
     *  
     * @author Eric 
     * @param cls 
     * @return 
     * @throws AppException 
     *//*  
    @SuppressWarnings("rawtypes")  
    public int findIntRowCountByHqlName(Class cls) throws AppException{  
        try{  
            Query query = sessionFactory.getCurrentSession().createQuery(" select count(c.id) from " + cls.getName() + " c ");  
            List list = query.list();  
            int rowCount = ((Number) list.get(0)).intValue();  
            return rowCount;  
        }catch(Exception e){  
            throw new AppException("查询记录总数异常，请联系管理员！",e);  
        }  
    }  
  
    *//** 
     *  
     * <br/>Description:根据HQL提供者别名与条件查询记录总数 
     *  
     * @author Eric 
     * @param hqlProviderSet 
     * @param queryName 
     * @param paramMap 
     * @return 
     * @throws AppException 
     *//*  
    
    @SuppressWarnings("rawtypes")  
    public int findIntRowCountByHqlName(IHqlProviderSet hqlProviderSet,String queryName,Map paramMap) throws AppException{  
        String hql;  
        try{  
            hql = hqlProviderSet.getHqlByQryName(queryName);  
            Query query = sessionFactory.getCurrentSession().createQuery(hql);  
            if(paramMap != null){  
                hqlArgs(paramMap,query);  
            }  
            List list = query.list();  
            int rowCount = ((Number) list.get(0)).intValue();  
            return rowCount;  
        }catch(Exception e){  
            throw new AppException("执行带参数的查询记录总数异常，请联系管理员！",e);  
        }  
    }  
  
    *//** 
     *  
     * <br/>Description:为Hibernate查询设置参数 
     *  
     * @author Eric 
     * @param argsMap 
     * @param query 
     *//*  
    @SuppressWarnings("rawtypes")  
    public void hqlArgs(Map argsMap,Query query){  
        Iterator itKey = argsMap.keySet().iterator();  
        while(itKey.hasNext()){  
            String key = (String) itKey.next();  
            @SuppressWarnings("unused")  
            Object obj = argsMap.get(key);  
            if(argsMap.get(key) instanceof List){  
                query.setParameterList(key,(List) argsMap.get(key));  
            }else{  
                query.setParameter(key,argsMap.get(key));  
            }  
        }  
    }  
  
    public SessionFactory getSessionFactory(){  
        return sessionFactory;  
    }  
  
    public void setSessionFactory(SessionFactory sessionFactory){  
        this.sessionFactory = sessionFactory;  
    }  */
}
